<!DOCTYPE html>
<html lang="zh-cn">
<head>
	
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>
支持上传的SimpleHTTPServer | 
穷折腾</title>
	<link rel="stylesheet" href="/static/css/style.css" />
	<link rel="stylesheet" href="/static/css/pygments.css" />
	<link rel="alternate" type="application/rss+xml" title="RSS" href="http://zqqf16.info/rss.xml" />
</head>
<body>
    <div id="container">
      <div id="main" role="main">
        <header>
		<h1>
支持上传的SimpleHTTPServer
</h1>
		</header>

     <nav>
		<span><a title="home page" class="" href="/">home</a></span>
		<span><a title="标签" class="" href="/tags/index.html">标签</a></span>
		<span><a title="订阅" class="" href="/rss.xml">订阅</a></span>
        <span><a href="/pages/about.html" title="关于">关于</a></span>
     </nav>

     <article class="content">
        <section class="post">
            
		<p>办公室有两台电脑，一个台式机，装着Ubuntu，主要用来开发。另一台笔记本，装着Windows，用来收发邮件，读写文档。为了方便两台机器的文件共享，在Ubuntu上装了Samba服务器。</p>
<p>但是公司的WiFi和台式机的有线不在同一个网段，这就导致了笔记本用WiFi的时候就不能用Samba。后来发现python自带的SimpleHTTPServer可以很方便的搭建HTTP服务器，用它从台式机向笔记本传文件很方便。</p>
<p>SimpleHTTPServer太Simple了，没有上传功能，从笔记本到台式机的时候不是很方便。于是乎找来SimpleHTTPServer.py好好研究一番，就有了下面的支持上传的SimpleHTTPServer：（或者移步<a href="https://github.com/zqqf16/SimpleHTTPServer">Github</a>）</p>
<div class="codehilite"><pre><span class="sd">&quot;&quot;&quot;Simple HTTP Server.</span>

<span class="sd">This module builds on BaseHTTPServer by implementing the standard GET</span>
<span class="sd">and HEAD requests in a fairly straightforward manner.</span>

<span class="sd">Support upload files</span>

<span class="sd">&quot;&quot;&quot;</span>

<span class="n">__version__</span> <span class="o">=</span> <span class="s">&quot;0.6&quot;</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;SimpleHTTPRequestHandler&quot;</span><span class="p">]</span>

<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">posixpath</span>
<span class="kn">import</span> <span class="nn">BaseHTTPServer</span>
<span class="kn">import</span> <span class="nn">urllib</span>
<span class="kn">import</span> <span class="nn">cgi</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">mimetypes</span>
<span class="k">try</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">cStringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
    <span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>

<span class="k">class</span> <span class="nc">SimpleHTTPRequestHandler</span><span class="p">(</span><span class="n">BaseHTTPServer</span><span class="o">.</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span>

    <span class="sd">&quot;&quot;&quot;Simple HTTP request handler with GET and HEAD commands.</span>

<span class="sd">    This serves files from the current directory and any of its</span>
<span class="sd">    subdirectories.  The MIME type for files is determined by</span>
<span class="sd">    calling the .guess_type() method.</span>

<span class="sd">    The GET and HEAD requests are identical except that the HEAD</span>
<span class="sd">    request omits the actual contents of the file.</span>

<span class="sd">    &quot;&quot;&quot;</span>

    <span class="n">server_version</span> <span class="o">=</span> <span class="s">&quot;SimpleHTTP/&quot;</span> <span class="o">+</span> <span class="n">__version__</span>

    <span class="k">def</span> <span class="nf">do_GET</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Serve a GET request.&quot;&quot;&quot;</span>
        <span class="n">f</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_head</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">f</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">copyfile</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">wfile</span><span class="p">)</span>
            <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">do_POST</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Serve a POST request.&quot;&quot;&quot;</span>
        <span class="n">form</span> <span class="o">=</span> <span class="n">cgi</span><span class="o">.</span><span class="n">FieldStorage</span><span class="p">(</span>
            <span class="n">fp</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">rfile</span><span class="p">,</span>
            <span class="n">headers</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">,</span>
            <span class="n">environ</span><span class="o">=</span><span class="p">{</span><span class="s">&#39;REQUEST_METHOD&#39;</span><span class="p">:</span> <span class="s">&#39;POST&#39;</span><span class="p">,</span>
                     <span class="s">&#39;CONTENT_TYPE&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">&#39;Content-Type&#39;</span><span class="p">],</span>
                     <span class="p">})</span>
        <span class="n">filename</span> <span class="o">=</span> <span class="n">form</span><span class="p">[</span><span class="s">&#39;file&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span>
        <span class="n">path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
        <span class="n">filepath</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">filepath</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">log_error</span><span class="p">(</span><span class="s">&#39;File </span><span class="si">%s</span><span class="s"> exist!&#39;</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
            <span class="n">filepath</span> <span class="o">+=</span> <span class="s">&#39;.new&#39;</span>

        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="s">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">form</span><span class="p">[</span><span class="s">&#39;file&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">do_GET</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">do_HEAD</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Serve a HEAD request.&quot;&quot;&quot;</span>
        <span class="n">f</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_head</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">f</span><span class="p">:</span>
            <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">send_head</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Common code for GET and HEAD commands.</span>

<span class="sd">        This sends the response code and MIME headers.</span>

<span class="sd">        Return value is either a file object (which has to be copied</span>
<span class="sd">        to the outputfile by the caller unless the command was HEAD,</span>
<span class="sd">        and must be closed by the caller under all circumstances), or</span>
<span class="sd">        None, in which case the caller has nothing further to do.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">path</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
        <span class="n">f</span> <span class="o">=</span> <span class="bp">None</span>
        <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">path</span><span class="p">):</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">):</span>
                <span class="c"># redirect browser - doing basically what apache does</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">301</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Location&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">+</span> <span class="s">&quot;/&quot;</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span>
                <span class="k">return</span> <span class="bp">None</span>
            <span class="k">for</span> <span class="n">index</span> <span class="ow">in</span> <span class="s">&quot;index.html&quot;</span><span class="p">,</span> <span class="s">&quot;index.htm&quot;</span><span class="p">:</span>
                <span class="n">index</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">index</span><span class="p">):</span>
                    <span class="n">path</span> <span class="o">=</span> <span class="n">index</span>
                    <span class="k">break</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">list_directory</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="n">ctype</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c"># Always read in binary mode. Opening files in text mode may cause</span>
            <span class="c"># newline translations, making the actual size of the content</span>
            <span class="c"># transmitted *less* than the content-length!</span>
            <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s">&#39;rb&#39;</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">send_error</span><span class="p">(</span><span class="mi">404</span><span class="p">,</span> <span class="s">&quot;File not found&quot;</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Content-type&quot;</span><span class="p">,</span> <span class="n">ctype</span><span class="p">)</span>
        <span class="n">fs</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">fstat</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Content-Length&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">fs</span><span class="p">[</span><span class="mi">6</span><span class="p">]))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Last-Modified&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">date_time_string</span><span class="p">(</span><span class="n">fs</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">f</span>

    <span class="k">def</span> <span class="nf">list_directory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Helper to produce a directory listing (absent index.html).</span>

<span class="sd">        Return value is either a file object, or None (indicating an</span>
<span class="sd">        error).  In either case, the headers are sent, making the</span>
<span class="sd">        interface the same as for send_head().</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="nb">list</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="k">except</span> <span class="n">os</span><span class="o">.</span><span class="n">error</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">send_error</span><span class="p">(</span><span class="mi">404</span><span class="p">,</span> <span class="s">&quot;No permission to list directory&quot;</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="nb">list</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">a</span><span class="p">:</span> <span class="n">a</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
        <span class="n">f</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
        <span class="n">displaypath</span> <span class="o">=</span> <span class="n">cgi</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">urllib</span><span class="o">.</span><span class="n">unquote</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">))</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 3.2 Final//EN&quot;&gt;&#39;</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;&lt;html&gt;</span><span class="se">\n</span><span class="s">&lt;title&gt;Directory listing for </span><span class="si">%s</span><span class="s">&lt;/title&gt;</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">displaypath</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;&lt;body&gt;</span><span class="se">\n</span><span class="s">&lt;h2&gt;Directory listing for </span><span class="si">%s</span><span class="s">&lt;/h2&gt;</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">displaypath</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;&#39;&#39;&lt;form action=&quot;&quot; enctype=&quot;multipart/form-data&quot; method=&quot;post&quot;&gt;</span><span class="se">\n</span><span class="s"></span>
<span class="s">                    &lt;input name=&quot;file&quot; type=&quot;file&quot; /&gt;</span>
<span class="s">                    &lt;input value=&quot;upload&quot; type=&quot;submit&quot; /&gt;</span>
<span class="s">                &lt;/form&gt;&#39;&#39;&#39;</span><span class="p">)</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;&lt;hr&gt;</span><span class="se">\n</span><span class="s">&lt;ul&gt;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">&#39;.&#39;</span><span class="p">):</span>
                <span class="k">continue</span>
            <span class="n">fullname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
            <span class="n">displayname</span> <span class="o">=</span> <span class="n">linkname</span> <span class="o">=</span> <span class="n">name</span>
            <span class="c"># Append / for directories or @ for symbolic links</span>
            <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">fullname</span><span class="p">):</span>
                <span class="n">displayname</span> <span class="o">=</span> <span class="n">name</span> <span class="o">+</span> <span class="s">&quot;/&quot;</span>
                <span class="n">linkname</span> <span class="o">=</span> <span class="n">name</span> <span class="o">+</span> <span class="s">&quot;/&quot;</span>
            <span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">islink</span><span class="p">(</span><span class="n">fullname</span><span class="p">):</span>
                <span class="n">displayname</span> <span class="o">=</span> <span class="n">name</span> <span class="o">+</span> <span class="s">&quot;@&quot;</span>
                <span class="c"># Note: a link to a directory displays with @ and links with /</span>
            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&#39;&lt;li&gt;&lt;a href=&quot;</span><span class="si">%s</span><span class="s">&quot;&gt;</span><span class="si">%s</span><span class="s">&lt;/a&gt;</span><span class="se">\n</span><span class="s">&#39;</span>
                    <span class="o">%</span> <span class="p">(</span><span class="n">urllib</span><span class="o">.</span><span class="n">quote</span><span class="p">(</span><span class="n">linkname</span><span class="p">),</span> <span class="n">cgi</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">displayname</span><span class="p">)))</span>
        <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;&lt;/ul&gt;</span><span class="se">\n</span><span class="s">&lt;hr&gt;</span><span class="se">\n</span><span class="s">&lt;/body&gt;</span><span class="se">\n</span><span class="s">&lt;/html&gt;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span>
        <span class="n">length</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>
        <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span>
        <span class="n">encoding</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">getfilesystemencoding</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Content-type&quot;</span><span class="p">,</span> <span class="s">&quot;text/html; charset=</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">encoding</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s">&quot;Content-Length&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">length</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">f</span>

    <span class="k">def</span> <span class="nf">translate_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Translate a /-separated PATH to the local filename syntax.</span>

<span class="sd">        Components that mean special things to the local file system</span>
<span class="sd">        (e.g. drive or directory names) are ignored.  (XXX They should</span>
<span class="sd">        probably be diagnosed.)</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c"># abandon query parameters</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;?&#39;</span><span class="p">,</span><span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;#&#39;</span><span class="p">,</span><span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">urllib</span><span class="o">.</span><span class="n">unquote</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
        <span class="n">words</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;/&#39;</span><span class="p">)</span>
        <span class="n">words</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">words</span><span class="p">)</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getcwd</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="n">words</span><span class="p">:</span>
            <span class="n">drive</span><span class="p">,</span> <span class="n">word</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitdrive</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>
            <span class="n">head</span><span class="p">,</span> <span class="n">word</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">word</span> <span class="ow">in</span> <span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">curdir</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">pardir</span><span class="p">):</span> <span class="k">continue</span>
            <span class="n">path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">word</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">path</span>

    <span class="k">def</span> <span class="nf">copyfile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">source</span><span class="p">,</span> <span class="n">outputfile</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Copy all data between two file objects.</span>

<span class="sd">        The SOURCE argument is a file object open for reading</span>
<span class="sd">        (or anything with a read() method) and the DESTINATION</span>
<span class="sd">        argument is a file object open for writing (or</span>
<span class="sd">        anything with a write() method).</span>

<span class="sd">        The only reason for overriding this would be to change</span>
<span class="sd">        the block size or perhaps to replace newlines by CRLF</span>
<span class="sd">        -- note however that this the default server uses this</span>
<span class="sd">        to copy binary data as well.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">shutil</span><span class="o">.</span><span class="n">copyfileobj</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">outputfile</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">log_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Log an error.</span>

<span class="sd">        Display error message in red color.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">format</span> <span class="o">=</span> <span class="s">&#39;</span><span class="se">\033</span><span class="s">[0;31m&#39;</span> <span class="o">+</span> <span class="n">format</span> <span class="o">+</span> <span class="s">&#39;</span><span class="se">\033</span><span class="s">[0m&#39;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log_message</span><span class="p">(</span><span class="n">format</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">guess_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Guess the type of a file.</span>

<span class="sd">        Argument is a PATH (a filename).</span>

<span class="sd">        Return value is a string of the form type/subtype,</span>
<span class="sd">        usable for a MIME Content-type header.</span>

<span class="sd">        The default implementation looks the file&#39;s extension</span>
<span class="sd">        up in the table self.extensions_map, using application/octet-stream</span>
<span class="sd">        as a default; however it would be permissible (if</span>
<span class="sd">        slow) to look inside the data to make a better guess.</span>

<span class="sd">        &quot;&quot;&quot;</span>

        <span class="n">base</span><span class="p">,</span> <span class="n">ext</span> <span class="o">=</span> <span class="n">posixpath</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">ext</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">extensions_map</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">extensions_map</span><span class="p">[</span><span class="n">ext</span><span class="p">]</span>
        <span class="n">ext</span> <span class="o">=</span> <span class="n">ext</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">ext</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">extensions_map</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">extensions_map</span><span class="p">[</span><span class="n">ext</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">extensions_map</span><span class="p">[</span><span class="s">&#39;&#39;</span><span class="p">]</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">inited</span><span class="p">:</span>
        <span class="n">mimetypes</span><span class="o">.</span><span class="n">init</span><span class="p">()</span> <span class="c"># try to read system mime.types</span>
    <span class="n">extensions_map</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">types_map</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
    <span class="n">extensions_map</span><span class="o">.</span><span class="n">update</span><span class="p">({</span>
        <span class="s">&#39;&#39;</span><span class="p">:</span> <span class="s">&#39;application/octet-stream&#39;</span><span class="p">,</span> <span class="c"># Default</span>
        <span class="s">&#39;.py&#39;</span><span class="p">:</span> <span class="s">&#39;text/plain&#39;</span><span class="p">,</span>
        <span class="s">&#39;.c&#39;</span><span class="p">:</span> <span class="s">&#39;text/plain&#39;</span><span class="p">,</span>
        <span class="s">&#39;.h&#39;</span><span class="p">:</span> <span class="s">&#39;text/plain&#39;</span><span class="p">,</span>
        <span class="p">})</span>

<span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">HandlerClass</span> <span class="o">=</span> <span class="n">SimpleHTTPRequestHandler</span><span class="p">,</span>
         <span class="n">ServerClass</span> <span class="o">=</span> <span class="n">BaseHTTPServer</span><span class="o">.</span><span class="n">HTTPServer</span><span class="p">):</span>
    <span class="n">BaseHTTPServer</span><span class="o">.</span><span class="n">test</span><span class="p">(</span><span class="n">HandlerClass</span><span class="p">,</span> <span class="n">ServerClass</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">test</span><span class="p">()</span>
</pre></div>


<p>代码主要复制于“SimpleHTTPServer.py”，主要做了一下修改：</p>
<ol>
<li>当列出目录的所有文件时，忽略掉Linux下的隐藏文件。（“.”开头的文件，我觉得隐藏文件没有必要显示）</li>
<li>修改了<code>list_directory</code>方法返回的页面，增加了一个上传文件表单。</li>
<li>增加了<code>do_POST</code>方法，用来处理POST请求。调用<code>cgi.FieldStorage</code>来获取上传的文件。</li>
<li>重写了<code>log_error</code>方法，将错误信息以红色显示。</li>
</ol>
<p>另外，SimpleHTTPServer基于BaseHTTPServer，如有兴趣可以参考官方文档。</p>
	</section>
	<section class="meta">
		<span class="tags">Tagged by 
			<a href="/tags/python.html">python</a>
		</span>

		<span class="time">&nbsp;<time datetime="2013-07-24">2013-07-24</time></span>
	</section>
	<!-- Duoshuo Comment BEGIN -->
<div class="ds-thread"></div>
<script type="text/javascript">
	var duoshuoQuery = {short_name:"zqqf16"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = 'http://static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		|| document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
</script>
<!-- Duoshuo Comment END -->

<hr/>


        </section>
     </article>
	 <div id="copy">&copy; Powered by <a href="https://github.com/zqqf16/zqqf16.github.com" title="Peanut">Peanut</a> | Themed by <a href="http://lhzhang.com" title="sext ii">sext ii</a></div>
      </div>
    </div> <!--! end of #container -->
	<script>
	  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
			(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
		m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
			})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

	  ga('create', 'UA-41282906-1', 'zqqf16.info');
	  ga('send', 'pageview');
	</script>
</body>
</html>
